//
//  CJExten+UIImage.swift
//  CJPack
//
//  Created by 陈警卫 on 2023/2/14.
//

import UIKit
import Foundation
import Photos

// MARK: 图片处理
public extension UIImage {
    
    /// 图片渲染
    func cj_imageTint(color: UIColor, blendMode: CGBlendMode = .destinationIn) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
        color.setFill()
        UIRectFill(rect)
        self.draw(in: rect, blendMode: .destinationIn, alpha: 1.0)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        if let image = image {
            return image.withRenderingMode(.alwaysOriginal)
        }
        return self
    }
    
    /// 创建纯色图片
    func cj_imageCreate(_ size: CGSize = CGSize(width: 1.0, height: 1.0), color: UIColor = .white) -> UIImage? {
        if size.width <= 0.0 || size.height <= 0.0 {
            return nil
        }
        let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
        let context = UIGraphicsGetCurrentContext()
        context?.setFillColor(color.cgColor)
        context?.fill(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    
    /// 创建纯色图片
    func cj_imageCreate(_ size: CGSize = CGSize(width: 1.0, height: 1.0), closure: (CGContext) -> ()) -> UIImage? {
        if size.width <= 0.0 || size.height <= 0.0 {
            return nil
        }
        let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0)
        let context = UIGraphicsGetCurrentContext()
        if let context = context {
            closure(context)
        }
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    
    /// 图片缩放
    func cj_imageResize(_ size: CGSize) -> UIImage? {
        if size.width <= 0.0 || size.height <= 0.0 {
            return nil
        }
        let originalSize = self.size
        let aspectWidth = size.width / originalSize.width
        let aspectHeight = size.height / originalSize.height
        let scaleFactor = min(aspectWidth, aspectHeight)
        let scaledSize = CGSize(width: originalSize.width * scaleFactor, height: originalSize.height * scaleFactor)
        
        let renderer = UIGraphicsImageRenderer(size: scaledSize)
        let resizedImage = renderer.image { _ in
            self.draw(in: CGRect(origin: .zero, size: scaledSize))
        }
        return resizedImage
    }
    
    /// 图片裁剪
    func cj_imageCrop(_ rect: CGRect) -> UIImage? {
        var rect = rect
        rect.origin.x *= scale
        rect.origin.y *= scale
        rect.size.width *= scale
        rect.size.height *= scale
        if rect.size.width <= 0 || rect.size.height <= 0 {
            return nil
        }
        if let cgImage = self.cgImage?.cropping(to: rect) {
            let image = UIImage(cgImage: cgImage)
            return image
        }
        return nil
    }
    
    /// 模糊图片
    func cj_imageBlur(_ blur: CGFloat) -> UIImage? {
        
        let ciImaage = CIImage(image: self)
        let filter = CIFilter(name: "CIBoxBlur")
        filter?.setValue(ciImaage, forKey: kCIInputImageKey)
        filter?.setValue(NSNumber(value: blur) , forKey: "inputRadius")
        
        let result: CIImage? = filter?.value(forKey: kCIOutputImageKey) as? CIImage
        guard let result = result else { return nil }
        let context = CIContext()
        let outImage = context.createCGImage(result, from: result.extent)
        guard let outImage = outImage else { return nil }
        let blueImage = UIImage(cgImage: outImage)
        return blueImage
    }
    
    /// 图片圆角边框
    func cj_imageCorner(_ radius: CGFloat,
                        corners: UIRectCorner = .allCorners,
                        borderWidth: CGFloat = 0,
                        borderColor: UIColor?,
                        borderLineJoin: CGLineJoin = .miter) -> UIImage? {
        
        UIGraphicsBeginImageContextWithOptions(size, false, scale)
        let context = UIGraphicsGetCurrentContext()
        let rect = CGRect(x: 0.0, y: 0.0, width: size.width, height: size.height)
        context?.scaleBy(x: 1, y: -1)
        context?.translateBy(x: 0, y: -rect.size.height)
        
        let minSize = min(size.width, size.height)
        if borderWidth < minSize/2 {
            let bzPath = UIBezierPath(roundedRect: CGRectInset(rect, borderWidth, borderWidth), byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: borderWidth))
            bzPath.close()
            context?.saveGState()
            bzPath.addClip()
            if let cgImage = cgImage {
                context?.draw(cgImage, in: rect)
            }
            context?.restoreGState()
        }
        
        if borderColor != nil && borderWidth < minSize/2 && borderWidth > 0 {
            let strokeInset = (floor(borderWidth * scale) + 0.5)/scale
            let strokeRect = CGRectInset(rect, strokeInset, strokeInset)
            let strokeRadius = radius > scale/2 ? radius - scale/2 : 0
            let bzPath = UIBezierPath(roundedRect: strokeRect, byRoundingCorners: corners, cornerRadii: CGSize(width: strokeRadius, height: borderWidth))
            bzPath.close()
            
            bzPath.lineWidth = borderWidth
            bzPath.lineJoinStyle = borderLineJoin
            borderColor?.setStroke()
            bzPath.stroke()
        }
        
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
    
    
    /// 图片拉伸
    /// isBubble true为中心拉伸 false为edge
    func cj_imageStrech(edge: inout UIEdgeInsets, isBubble: Bool = false, resizingMode: UIImage.ResizingMode = .stretch) -> UIImage {
        if isBubble {
            let top = size.height * 0.5
            let left = size.width * 0.5
            let bottom = size.height * 0.5
            let right = size.width * 0.5
            edge = UIEdgeInsets(top: top, left: left, bottom: bottom, right: right)
        }
        let image = resizableImage(withCapInsets: edge, resizingMode: resizingMode)
        return image
    }
    
    /// 图片质量压缩
    func cj_imageCompress(dataSize: Int = 1024 * 1024 * 2) -> Data? {
        let maxSize = dataSize
        var quality = 0.9
        var data = jpegData(compressionQuality: quality)
        
        while (data?.count ?? 0) > maxSize {
            if quality <= 0.2 {
                break
            }
            quality = quality - 0.1
            data = jpegData(compressionQuality: quality)
            if (data?.count ?? 0) <= dataSize {
                break
            }
        }
        return data
    }
}

// MARK: 图片工具
public extension UIImage {
    
    /// 保存图片到相册
    func cj_savedPhotoLibrary(_ completion: @escaping ((Bool, Error?) -> Void)) {
        PHPhotoLibrary.shared().performChanges {
            PHAssetChangeRequest.creationRequestForAsset(from: self)
        } completionHandler: { (success, error) in
            completion(success, error)
        }
    }
}
